﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Scan
{
    public partial class ProgressDialog : Form
    {
        private int minimum = 0;
        private int maximum = 30;
        private int position = 0;


        private int curWidth = 0;
        private Rectangle rect = new Rectangle(15 + 2, 15 + 2, 180 - 4, 22 - 4); //滚动条位置，不包括边框

        Bitmap backBmp;
        Bitmap foreBmp;


        /// <summary>
        /// 父窗体
        /// </summary>
        public MainForm ParentForm
        {
            get { return parentForm; }
            set { parentForm = value; }
        }
        protected MainForm parentForm;


        public ProgressDialog()
        {
            InitializeComponent();

            backBmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
            Graphics g = Graphics.FromImage(backBmp);
            IntPtr hDC = g.GetHdc();

            Win32.RECT rc = new Win32.RECT(0, 0, this.ClientSize.Width, this.ClientSize.Height);
            Win32.FillRect(hDC, ref rc, Win32.GetStockObject(Win32.WHITE_BRUSH));

            IntPtr borderPen = Win32.CreatePen(Win32.PS_SOLID, 1, Win32.RGB(112, 112, 112));
            IntPtr hOldPen = Win32.SelectObject(hDC, borderPen);
            IntPtr hOldBrush = Win32.SelectObject(hDC, Win32.GetStockObject(Win32.WHITE_BRUSH));
            Win32.RoundRect(hDC, rect.Left - 2, rect.Top - 2, rect.Right + 2, rect.Bottom + 2, 6, 6);
            Win32.SelectObject(hDC, hOldPen);
            Win32.SelectObject(hDC, hOldBrush);
            Win32.DeleteObject(borderPen);

            g.ReleaseHdc(hDC);
            g.Dispose();

            foreBmp = new Bitmap(rect.Width * 2, rect.Height);
            g = Graphics.FromImage(foreBmp);
            hDC = g.GetHdc();

            Win32.GRADIENT_RECT[] gra = new Win32.GRADIENT_RECT[] {
                    new Win32.GRADIENT_RECT(0, 1),
                    new Win32.GRADIENT_RECT(2, 3),
                    new Win32.GRADIENT_RECT(4, 5),
                    new Win32.GRADIENT_RECT(6, 7)};


            Win32.TRIVERTEX[] tva = new Win32.TRIVERTEX[]{
                    new Win32.TRIVERTEX(0, 0, 0xCD, 0xFF, 0xCD, 0x00),
                    new Win32.TRIVERTEX(rect.Width, rect.Height / 2, 0x9C, 0xEE, 0xAC, 0x00),
                    new Win32.TRIVERTEX(0, rect.Height / 2, 0x00, 0xD3, 0x28, 0x00),
                    new Win32.TRIVERTEX(rect.Width, rect.Height, 0x1C, 0xE2, 0x33, 0x00),

                    new Win32.TRIVERTEX(rect.Width, 0, 0xf2, 0xf2, 0xf2, 0x00),
                    new Win32.TRIVERTEX(rect.Width * 2, rect.Height / 2, 0xEB, 0xEB, 0xEB, 0x00),
                    new Win32.TRIVERTEX(rect.Width, rect.Height / 2, 0xDD, 0xDD, 0xDD, 0x00),
                    new Win32.TRIVERTEX(rect.Width * 2, rect.Height, 0xCF, 0xCF, 0xCF, 0x00)};

            Win32.GradientFill(hDC, tva, 8, gra, 4, Win32.GRADIENT_FILL_RECT_V);

            g.ReleaseHdc(hDC);
            g.Dispose();
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            if (++position > maximum)
            {
                position = minimum;
            }

            int newWidth = rect.Width * (position - minimum) / (maximum - minimum);
            if (newWidth == 0)
            {
                this.Invalidate(new Rectangle(rect.Left, rect.Top, curWidth, rect.Height));
            }
            else
            {
                this.Invalidate(new Rectangle(rect.Left + curWidth, rect.Top, newWidth - curWidth, rect.Height));
            }
            curWidth = newWidth;

        }

        private void ProgressDialog_Deactivate(object sender, EventArgs e)
        {
            this.Activate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            if (this.Site != null && this.Site.DesignMode)
            {

            }
            else
            {
                if (!rect.Contains(e.ClipRectangle))
                {
                    e.Graphics.DrawImage(backBmp, e.ClipRectangle, e.ClipRectangle, GraphicsUnit.Pixel);
                }

                if (rect.IntersectsWith(e.ClipRectangle))
                {
                    Rectangle rc = Rectangle.Intersect(rect, e.ClipRectangle);
                    Rectangle rc2 = new Rectangle(rect.Width - curWidth + (rc.Left - rect.Left), 0, rc.Width, rc.Height);

                    e.Graphics.DrawImage(foreBmp, rc, rc2, GraphicsUnit.Pixel);
                }
            }
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            //base.OnPaintBackground(e);
        }


        public void ShowProgress(string title, bool canCancel)
        {
            this.Text = title;
            //this.cancel.Enabled = canCancel;
            this.cancel.Visible = false;

            if (!this.Visible)
            {
                this.Location = new Point(20, 120);
                position = 0;
                timer.Enabled = true;
                this.Show();
                // 使得：每次 Visbile 由 false -> true 时，呈现的滚动条均从 position = 0 开始，
                // 否则会先呈现上次的 position 值，然后500毫秒后(timer tick 执行)才从 position = 0 开始滚动
                timer_Tick(null, null); 
            }
        }

        public void HideProgress()
        {
            timer.Enabled = false;
            this.Hide();
        }

        private void cancel_Click(object sender, EventArgs e)
        {
            //this.Text = "请稍候,数据传输正在中止";
            //this.ParentForm.TransMgr.Abort();
        }
    }
}